package br.com.mynage.dao.impl;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;

import br.com.mynage.dao.Database;
import br.com.mynage.dao.GenericDao;

/** 
 * Implemneta��o da classes gen�rica de persistencia de dados.
 * */
public abstract class GenericDaoImpl<T>  implements GenericDao<T> {	
	
	private void change(T c, OperacaoDatabase op){
		EntityManager em = Database.getInstance().getEntityManager();
		em.getTransaction().begin();
		switch (op) {
			case INSERIR:
				em.persist(c);
				break;
			case ALTERAR:
				em.merge(c);
				break;
			case REMOVER:
				em.remove(c);
				break;
		}
		em.getTransaction().commit();
		em.close();
	}
	
	public void insert(T c){
		change(c, OperacaoDatabase.INSERIR);
	}
	public void update(T c){
		change(c, OperacaoDatabase.ALTERAR);
	}
	public void remove(T c){
		change(c, OperacaoDatabase.REMOVER);
	}
	
	public T findByPrimaryKey(int id){
		EntityManager em = Database.getInstance().getEntityManager();
		T c = em.find(getClassType(), id);
		em.close();
		return c;
	}
	
	public List<T> findAll(){
		EntityManager em = getEntityManager();
		CriteriaBuilder builder = em.getCriteriaBuilder();
		CriteriaQuery<T> query = builder.createQuery(getClassType());
		TypedQuery<T> typedQuery = em.createQuery(query.select(query.from(getClassType())));
		List<T> c = typedQuery.getResultList();
		em.close();
		return c;
	}
	
	@SuppressWarnings("unchecked")
	public List<T> getByField(String coluna,Object valor){
		String tabela = getClassType().getSimpleName();
		String jpql = "from "+tabela+ " where "+coluna+" like :valor";
		EntityManager em = getEntityManager();
		Query q = em.createQuery(jpql);
		q.setParameter("valor", "%"+valor+"%");
		List<T> retorno = q.getResultList();
		em.close();
		return retorno;
	}
		
	protected EntityManager getEntityManager(){
		return Database.getInstance().getEntityManager();
	}
	
	public abstract Class<T> getClassType();

}

enum OperacaoDatabase {
	INSERIR,ALTERAR,REMOVER;
}

